package com.erpanderp.wam.ac.view.travel;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.AjaxBehaviorEvent;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.swing.SwingWorker;

import org.primefaces.component.menuitem.MenuItem;
import org.primefaces.component.selectonebutton.SelectOneButton;
import org.primefaces.component.selectonemenu.SelectOneMenu;

import com.erpanderp.wam.ac.model.entity.travel.Logistics;
import com.erpanderp.wam.ac.model.entity.travel.TravelExpenseAmount;
import com.erpanderp.wam.ac.model.entity.travel.TravelLogistics;
import com.erpanderp.wam.ac.model.entity.travel.TravelRequest;
import com.erpanderp.wam.ac.model.service.travel.LogisticsDAO;
import com.erpanderp.wam.ac.model.service.travel.TravelRequestDAO;
import com.erpanderp.wam.usm.model.entity.user.WAMUser;
import com.erpanderp.wam.usm.model.service.user.EmployeeAndReportingDAO;
import com.erpanderp.wam.util.CommonLookup;
import com.erpanderp.wam.util.EmailUtil;
import com.erpanderp.wam.util.ValidationUtil;
import com.erpanderp.wam.util.WAMHostManager;

@ManagedBean
@ViewScoped
public class CreateTravelRequestBean implements Serializable {

	private static final long serialVersionUID = 1L;

	HttpSession session = (HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true);
	private WAMUser wamUser = (WAMUser) session.getAttribute(CommonLookup.SESSION_ATTRIBUTE_WAMUSER);
	HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
	ServletContext context = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();

	private TravelRequest travelRequest = new TravelRequest();
	private Map<String, String> travelModesMap = CommonLookup.getTravelModesMap();
	private Map<String, String> natureOfWorksMap = CommonLookup.getNatureOfWorksMap();
	private Map<String, String> reimbursedByMap = CommonLookup.getReimbursedByMap();
	private List<TravelLogistics> logistics;
	
	String TRAVEL_TYPE = CommonLookup.TRAVEL_DOMESTIC_VALUE;
	LogisticsDAO travelLogisticsDAO = new LogisticsDAO();
	EmployeeAndReportingDAO employeeAndReportingDAO = new EmployeeAndReportingDAO();
	TravelRequestDAO travelRequestDAO = new TravelRequestDAO();
	EmailUtil emailUtil;
	String EMAIL_MESSAGE;

	private Float advancePaymentINR;
	private Float advancePaymentUSD;
	
	boolean FORM_VALID;
	
	public CreateTravelRequestBean() {
		if(wamUser != null){
			travelRequest.setEmployee(wamUser.getEmployee());
			travelRequest.setTravelType(TRAVEL_TYPE);
			travelRequest.setRequestDate(new Date());
			travelRequest.setTravelRequestCode(CommonLookup.getAutoGeneratedTravelRequestCode(wamUser.getEmployeeCode(), CommonLookup.TRAVEL_DOMESTIC_VALUE));
			travelRequest.setTravelFromCountry_DO("India");
			travelRequest.setTravelToCountry_DO("India");
			travelRequest.setApprover(employeeAndReportingDAO.getEmployeeReportingDetail(wamUser.getEmployee().getEmployeeId()).getProjectManager());
			List temp = travelLogisticsDAO.getLogistics();
			logistics = new ArrayList<TravelLogistics>();
			for(Logistics logistic : (List<Logistics>) temp){
				TravelLogistics travelLogistics = new TravelLogistics();
				travelLogistics.setLogistics(logistic);
				logistics.add(travelLogistics);
			}
			travelRequest.getTravelLogistics().addAll(logistics);
		}		
	}

	public void travelTypeChangeListener(ActionEvent e) {
		TRAVEL_TYPE = ((MenuItem)e.getComponent()).getValue().toString();
		travelRequest = new TravelRequest();
		travelRequest.setEmployee(wamUser.getEmployee());
		travelRequest.setRequestDate(new Date());
		travelRequest.setTravelRequestCode(CommonLookup.getAutoGeneratedTravelRequestCode(wamUser.getEmployeeCode(), CommonLookup.TRAVEL_DOMESTIC_VALUE));
		travelRequest.setApprover(employeeAndReportingDAO.getEmployeeReportingDetail(wamUser.getEmployee().getEmployeeId()).getProjectManager());
		travelRequest.setTravelType(TRAVEL_TYPE);
		
		travelRequest.setTravelFromCountry_DO("India");
		travelRequest.setTravelToCountry_DO("India");
		
		travelRequest.setTravelRequestCode(CommonLookup.getAutoGeneratedTravelRequestCode(wamUser.getEmployeeCode(), travelRequest.getTravelType()));
		travelRequest.getTravelLogistics().addAll(logistics);
	}

	public void submitRequest(ActionEvent e){
		System.out.println("Submitting...");
		validate();
		if(FORM_VALID){
			travelRequest.setCreateDate(new Date());
			travelRequest.setCreatedBy(wamUser.getEmployee().getFirstName());
			travelRequest.setStatus(CommonLookup.STATUS_ACTIVE);
			travelRequest.setTravelStatus(CommonLookup.TRAVEL_REQUEST_STATUS_INPROCESS);
			
			for(TravelLogistics travelLogistics : travelRequest.getTravelLogistics()){
				travelLogistics.setCreateDate(new Date());
				travelLogistics.setCreatedBy(wamUser.getEmployee().getFirstName());
				travelLogistics.setStatus(CommonLookup.STATUS_ACTIVE);
				travelLogistics.setTravelRequest(travelRequest);
			}
			System.out.println("Server "  + request.getServerName() + " " + request.getServerPort());
			generateTravelExpenseAmounts();
			if(travelRequestDAO.createTravelRequest(travelRequest) != null){
				//reset
				System.out.println("AT CALLER METHOD: " + sendMessage());
				
				generateTravelLogistics();
				FacesContext.getCurrentInstance().addMessage("", new FacesMessage(FacesMessage.SEVERITY_INFO, "Travel Request has been created successfully.", ""));
			}else{
				FacesContext.getCurrentInstance().addMessage("", new FacesMessage(FacesMessage.SEVERITY_ERROR, "Failed to create Travel Request. Please try again.", ""));
			}
		}
	}
	
	/**
	 * generate two default advanceamount
	 */
	private void generateTravelExpenseAmounts(){
		TravelExpenseAmount travelExpenseAmount = new TravelExpenseAmount();
		travelExpenseAmount.setAmount(advancePaymentINR);
		travelExpenseAmount.setCurrency("INR");
		travelExpenseAmount.setAmountType(CommonLookup.TRAVEL_EXPENSE_TYPE_ADVANCE);
		travelExpenseAmount.setCreateDate(new Date());
		travelExpenseAmount.setCreatedBy(wamUser.getEmployeeCode());
		travelExpenseAmount.setStatus(CommonLookup.STATUS_ACTIVE);
		travelExpenseAmount.setTravelRequest(travelRequest);
		travelRequest.getTravelExpenseAmounts().add(travelExpenseAmount);
		
		if(!TRAVEL_TYPE.equals(CommonLookup.TRAVEL_DOMESTIC_VALUE)){
			travelExpenseAmount = new TravelExpenseAmount();
			travelExpenseAmount.setAmount(advancePaymentINR);
			travelExpenseAmount.setCurrency("USD");
			travelExpenseAmount.setAmountType(CommonLookup.TRAVEL_EXPENSE_TYPE_ADVANCE);
			travelExpenseAmount.setCreateDate(new Date());
			travelExpenseAmount.setCreatedBy(wamUser.getEmployeeCode());
			travelExpenseAmount.setStatus(CommonLookup.STATUS_ACTIVE);
			travelExpenseAmount.setTravelRequest(travelRequest);
			travelRequest.getTravelExpenseAmounts().add(travelExpenseAmount);	
		}
				
	}
	
	/**
	 * Used for regenerating/resetting travel logistics after form submit
	 */
	private void generateTravelLogistics(){
		travelRequest = new TravelRequest();
		travelRequest.setEmployee(wamUser.getEmployee());
		travelRequest.setRequestDate(new Date());
		travelRequest.setTravelRequestCode(CommonLookup.getAutoGeneratedTravelRequestCode(wamUser.getEmployeeCode(), CommonLookup.TRAVEL_DOMESTIC_VALUE));
		travelRequest.setApprover(employeeAndReportingDAO.getEmployeeReportingDetail(wamUser.getEmployee().getEmployeeId()).getProjectManager());
		travelRequest.setTravelType(TRAVEL_TYPE);
		travelRequest.setTravelRequestCode(CommonLookup.getAutoGeneratedTravelRequestCode(wamUser.getEmployeeCode(), travelRequest.getTravelType()));
		travelRequest.setTravelFromCountry_DO("India");
		travelRequest.setTravelToCountry_DO("India");
		
		logistics = new ArrayList<TravelLogistics>();
		
		List temp = travelLogisticsDAO.getLogisticsByLogistisType(CommonLookup.TRAVEL_DOMESTIC_VALUE);
		for(Logistics logistic : (List<Logistics>) temp){
			TravelLogistics travelLogistics = new TravelLogistics();
			travelLogistics.setLogistics(logistic);
			logistics.add(travelLogistics);
		}	
			
	}
	
	public String sendMessage(){
		Map<String, String> hostsMap = WAMHostManager.getWAMHosts(context);
		String domainName = context.getInitParameter("domainName");
		emailUtil = new EmailUtil();
		if(hostsMap.get(CommonLookup.DEV_EMAIL) == null){
			String[] to = {travelRequest.getApprover().getEmail()};
			emailUtil.setRecieverAddresses(to);
		}else{
			String[] to = {hostsMap.get(CommonLookup.DEV_EMAIL)};
			emailUtil.setRecieverAddresses(to);
		}
		String requestURL = "ac/travel/approvetravelrequest.html?trcode=" + travelRequest.getTravelRequestCode();
		String privateLink = "http://" + hostsMap.get(CommonLookup.PRIVATEHOST) + "/" + domainName + "/" + requestURL;
		String publicLink = "http://" + hostsMap.get(CommonLookup.PUBLICHOST) + "/"	+ domainName + "/" + requestURL;
		SimpleDateFormat formatter = new SimpleDateFormat("dd-MMM-yyyy");
		String messageString = "Dear " + travelRequest.getApprover().getFirstName() + " " + travelRequest.getApprover().getLastName() + "" +
								",<br />" +
								"<h3>New Travel Request Details</h3>" +
								"<table style='border: 1px solid #d9d9d9;'>" +
						        "<tr> <td>Employee Code </td><td> : </td><td>" + wamUser.getEmployee().getEmployeeCode() + " </td></tr>" +
						        "<tr> <td>Employee Name</td><td> : </td> <td>" + wamUser.getEmployee().getFirstName() + " </td></tr>" +
						        "<tr> <td>Travel Request Code</td><td> : </td> <td>" + travelRequest.getTravelRequestCode() + "</td></tr>" +
						        "<tr> <td>Travel Start Date</td><td> : </td> <td>" + formatter.format(travelRequest.getPeriodFrom()) + "</td></tr>" +
						        "<tr> <td>Travel Return Date</td><td> : </td> <td>" + formatter.format(travelRequest.getPeriodTo()) + "</td></tr>" +
						        "</table><br/>"+								
						        "<a style='color:#FF9933;font-weight: bold;' href=\""+
						        privateLink + "\">" + "Please click here to approve/reject travel request" + "</a /><br />"+
								"(Employees who are in Hyderabad office)"+"<br /><br />"+
								"<a style='color:#FF9933;font-weight: bold;' href=\""+
								publicLink + "\">" + "Please click here to approve/reject travel request" + "</a /><br />"+
								"(out side Hyderabad office)"+"<br /><br />"+
								
								"Thanks & Regards, <br />"+CommonLookup.WAM_DEVTEAM_SIGNATURE;;
		
		
		emailUtil.setMessage(messageString);

		emailUtil.setSenderEmail("podquick@erpanderp.com", "WAM - Dev Team");
		emailUtil.setSubject("WAM - Travel Request (" + travelRequest.getTravelRequestCode() + ")");

		SwingWorker worker = new SwingWorker<String, Object>() {
			@Override
			protected String doInBackground() throws Exception {
				EMAIL_MESSAGE = emailUtil.processAndSendEmail();
				return null;
			}

			@Override
			protected void done() {
					System.out.println("DONE " + EMAIL_MESSAGE);		
			}
		};
		worker.execute();
		System.out.println( "BEFORE RETURNING: " + EMAIL_MESSAGE);
		return EMAIL_MESSAGE;
	}
	
	public void validate(){
		FORM_VALID = true;		
		
		boolean START_DATE_EMPTY, END_DATE_EMPTY;
		if(ValidationUtil.isEmpty(travelRequest.getEmergencyContact(), "Emergency Contact", "emergencyContact", FacesContext.getCurrentInstance()) != null){
			FORM_VALID = false;
		}
		
		if(ValidationUtil.isEmpty(travelRequest.getPeriodFrom() == null ? null : travelRequest.getPeriodFrom().toString(), "Travel Period From", "travelPeriodFrom", FacesContext.getCurrentInstance()) != null){
			FORM_VALID = false;
			START_DATE_EMPTY = true;
		}else{
			START_DATE_EMPTY = false;
		}
			
		
		if(ValidationUtil.isEmpty(travelRequest.getPeriodTo() == null ? null : travelRequest.getPeriodTo().toString(), "Travel Period To", "travelPeriodTo", FacesContext.getCurrentInstance()) != null){
			FORM_VALID = false;
			END_DATE_EMPTY = true;
		}else{
			END_DATE_EMPTY = false;
		}
		
		if(TRAVEL_TYPE.equals(CommonLookup.TRAVEL_DOMESTIC_VALUE)){
			if(ValidationUtil.isEmpty(travelRequest.getTravelFrom_DO(), "Source City (Domestic)", "sourceCity", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
			if(ValidationUtil.isEmpty(travelRequest.getTravelFromCountry_DO(), "Source Country (Domestic)", "sourceCountry", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
			if(ValidationUtil.isEmpty(travelRequest.getTravelTo_DO(), "Destination City (Domestic)", "destinationCity", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
			if(ValidationUtil.isEmpty(travelRequest.getTravelToCountry_DO(), "Destination Country (Domestic)", "destinationCountry", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
		}
		
		if(TRAVEL_TYPE.equals(CommonLookup.TRAVEL_OVERSEAS_VALUE)){
			if(ValidationUtil.isEmpty(travelRequest.getTravelFrom_OS(), "Source City (Overseas)", "sourceCity", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
			if(ValidationUtil.isEmpty(travelRequest.getTravelFromCountry_OS(), "Source Country (Overseas)", "sourceCountry", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
			if(ValidationUtil.isEmpty(travelRequest.getTravelTo_OS(), "Destination City (Overseas)", "destinationCity", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
			if(ValidationUtil.isEmpty(travelRequest.getTravelToCountry_OS(), "Destination Country (Overseas)", "destinationCountry", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
		}
		
		if(TRAVEL_TYPE.equals(CommonLookup.TRAVEL_BOTH_VALUE)){
			if(ValidationUtil.isEmpty(travelRequest.getTravelFrom_DO(), "Source City (Domestic)", "sourceCity", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
			if(ValidationUtil.isEmpty(travelRequest.getTravelFromCountry_DO(), "Source Country (Domestic)", "sourceCountry", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
			if(ValidationUtil.isEmpty(travelRequest.getTravelTo_DO(), "Destination City (Domestic)", "destinationCity", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
			if(ValidationUtil.isEmpty(travelRequest.getTravelToCountry_DO(), "Destination Country (Domestic)", "destinationCountry", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
			if(ValidationUtil.isEmpty(travelRequest.getTravelFrom_OS(), "Source City (Overseas)", "sourceCity", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
			if(ValidationUtil.isEmpty(travelRequest.getTravelFromCountry_OS(), "Source Country (Overseas)", "sourceCountry", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
			if(ValidationUtil.isEmpty(travelRequest.getTravelTo_OS(), "Destination City (Overseas)", "destinationCity", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
			if(ValidationUtil.isEmpty(travelRequest.getTravelToCountry_OS(), "Destination Country (Overseas)", "destinationCountry", FacesContext.getCurrentInstance()) != null)
				FORM_VALID = false;
		}	
		
		if(!START_DATE_EMPTY && !END_DATE_EMPTY){
			System.out.println(travelRequest.getPeriodFrom());
			System.out.println(travelRequest.getPeriodTo());
			System.out.println(travelRequest.getPeriodFrom().equals(travelRequest.getPeriodFrom()));
			System.out.println(travelRequest.getPeriodFrom() == travelRequest.getPeriodFrom());
			if(!(travelRequest.getPeriodFrom().before(travelRequest.getPeriodTo()) || travelRequest.getPeriodFrom().equals(travelRequest.getPeriodTo()))){
				FacesContext.getCurrentInstance().addMessage("", new FacesMessage(FacesMessage.SEVERITY_WARN, "Period From should be before Period To.", ""));
				FORM_VALID = false;
			}
		}
		
		if(ValidationUtil.isEmpty(travelRequest.getClient(), "Client", "client", FacesContext.getCurrentInstance()) != null)
			FORM_VALID = false;
				
		if(ValidationUtil.isEmpty(travelRequest.getClientLocation(), "Client Location", "clientLocation", FacesContext.getCurrentInstance()) != null)
			FORM_VALID = false;
		
		System.out.println("FORM VALIDITY: " + FORM_VALID);
	}
	
	// GENERATE SETTERS AND GETTERS
	
	public WAMUser getWamUser() {
		return wamUser;
	}

	public void setWamUser(WAMUser wamUser) {
		this.wamUser = wamUser;
	}
	public Map<String, String> getTravelModesMap() {
		return travelModesMap;
	}

	public void setTravelModesMap(Map<String, String> travelModesMap) {
		this.travelModesMap = travelModesMap;
	}

	public Map<String, String> getNatureOfWorksMap() {
		return natureOfWorksMap;
	}

	public void setNatureOfWorksMap(Map<String, String> natureOfWorksMap) {
		this.natureOfWorksMap = natureOfWorksMap;
	}	

	public Map<String, String> getReimbursedByMap() {
		return reimbursedByMap;
	}

	public void setReimbursedByMap(Map<String, String> reimbursedByMap) {
		this.reimbursedByMap = reimbursedByMap;
	}

	public TravelRequest getTravelRequest() {
		return travelRequest;
	}

	public void setTravelRequest(TravelRequest travelRequest) {
		this.travelRequest = travelRequest;
	}

	public List<TravelLogistics> getLogistics() {
		return logistics;
	}

	public void setLogistics(List<TravelLogistics> logistics) {
		this.logistics = logistics;
	}

	public Float getAdvancePaymentINR() {
		return advancePaymentINR;
	}

	public void setAdvancePaymentINR(Float advancePaymentINR) {
		this.advancePaymentINR = advancePaymentINR;
	}

	public Float getAdvancePaymentUSD() {
		return advancePaymentUSD;
	}

	public void setAdvancePaymentUSD(Float advancePaymentUSD) {
		this.advancePaymentUSD = advancePaymentUSD;
	}

}
